﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using MvcWebScraper.Core.Parsers;

namespace MvcWebScraper.Core
{
	public enum Carrier
	{
		Unknown,
		All,
		DoCoMo,
		// ReSharper disable InconsistentNaming
		au,
		// ReSharper restore InconsistentNaming
		Softbank,
		Willcom
	}

	public class MobileScrapeInfo
	{
		public Type ScraperType { get; set; }
		public Uri Uri { get; set; }
		public Encoding Encoding { get; set; }
	}

	public class MobileCIDRScraper
	{
		private IRequestProvider _provider = new HttpRequestProvider();

		public IRequestProvider Provider
		{
			get
			{
				return _provider;
			}

			set
			{
				_provider = value;
			}
		}

		private readonly Dictionary<Carrier, MobileScrapeInfo> _scrapers =
			new Dictionary<Carrier, MobileScrapeInfo>
				{
					{Carrier.DoCoMo, new MobileScrapeInfo
					                 	{
					                 		ScraperType = typeof (DoCoMoCIDRParser),
											Uri=new Uri("http://www.nttdocomo.co.jp/service/imode/make/content/ip/"),
											Encoding = Encoding.GetEncoding(932)
					                 	}},
					{Carrier.au, new MobileScrapeInfo
					                 	{
					                 		ScraperType = typeof (AuCIDRParser),
											Uri=new Uri("http://www.au.kddi.com/ezfactory/tec/spec/ezsava_ip.html"),
											Encoding = Encoding.GetEncoding(932)
					                 	}},
					{Carrier.Softbank, new MobileScrapeInfo
					                 	{
					                 		ScraperType = typeof (SoftbankCIDRParser),
											Uri=new Uri("http://creation.mb.softbank.jp/web/web_ip.html"),
											Encoding = Encoding.GetEncoding(932)
					                 	}},
					{Carrier.Willcom, new MobileScrapeInfo
					                 	{
					                 		ScraperType = typeof (WillcomCIDRParser),
											Uri=new Uri("http://www.willcom-inc.com/ja/service/contents_service/create/center_info/index.html"),
											Encoding = Encoding.GetEncoding(932)
					                 	}}
				};

		public IEnumerable<Carrier> AllCarrier
		{
			get
			{
				return _scrapers.Select(s => s.Key);
			}
		}

		public IEnumerable<string> LoadCarrier(Carrier carrier)
		{
			var result = new List<string>();

			var info = _scrapers[carrier];
			var scraper = TypeDescriptor.CreateInstance(null, info.ScraperType, null, null) as MobileCIDRScraper<List<string>>;
			var html = Provider.Load(info.Uri, info.Encoding);

			if (scraper != null) result.AddRange(scraper.Invoke(html));

			return result;
		}

		public IDictionary<Carrier, IEnumerable<string>> Load(Carrier carrier)
		{
			if (carrier == Carrier.All)
				return (
						from c in AllCarrier
				       	select new {carrier = c, cidr = LoadCarrier(c)}
					   ).ToDictionary(key => key.carrier, value => value.cidr);

			return new Dictionary<Carrier, IEnumerable<string>> { { carrier, LoadCarrier(carrier) } };
		}
	}
}
